package com.ajmd.onlineexam.service;

import com.ajmd.onlineexam.entity.*;
import com.ajmd.onlineexam.enumeration.StaticFinalValue;
import com.ajmd.onlineexam.mapper.ImageMapper;
import com.ajmd.onlineexam.mapper.OptionMapper;
import com.ajmd.onlineexam.mapper.TestPaperMapper;
import com.ajmd.onlineexam.mapper.TestPaperQuestionMapper;
import com.ajmd.onlineexam.vo.OptionVO;
import com.ajmd.onlineexam.vo.QuestionVO;
import com.ajmd.onlineexam.vo.TestPaperQuestionVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author ajmd
 * @since 2023/4/28 15:12
 */
@Service
public class TestPaperQuestionService {
    @Resource
    private TestPaperQuestionMapper testPaperQuestionMapper;
    @Resource
    private TestPaperMapper testPaperMapper;
    @Resource
    private QuestionService questionService;
    @Resource
    private OptionMapper optionMapper;
    @Resource
    private OptionService optionService;
    @Resource
    private ImageMapper imageMapper;
    @Resource
    private RedisTemplate redisTemplate;

    public List<TestPaperQuestionVO> getTestPaperQuestion(String testPaperId){

        //先从redis中获取
        List<TestPaperQuestionVO> redisTPQuestionVOS = (List<TestPaperQuestionVO>) redisTemplate.opsForValue().get(testPaperId);
        if(ObjectUtils.isNotEmpty(redisTPQuestionVOS)){
            return redisTPQuestionVOS;
        }
        List<TestPaperQuestionVO> tPQuestionVOS = new ArrayList<>();

        //根据 testPaperId 查询所有试卷试题
        LambdaQueryWrapper<TestPaperQuestionPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TestPaperQuestionPO::getTestPaperId,testPaperId)
                .orderByAsc(TestPaperQuestionPO::getSort);
        List<TestPaperQuestionPO> tPQuestionPOList = testPaperQuestionMapper.selectList(queryWrapper);


        if(ObjectUtils.isEmpty(tPQuestionPOList)){
            return tPQuestionVOS;
        }

        //提取试卷试题id
        List<String> tPQuestionIds = tPQuestionPOList.stream().map(TestPaperQuestionPO::getId).collect(Collectors.toList());
        //查询所有选项
        LambdaQueryWrapper<OptionPO> optionQueryWrapper = new LambdaQueryWrapper<>();
        optionQueryWrapper.in(OptionPO::getBelongQuestionId,tPQuestionIds)
                .orderByAsc(OptionPO::getOptionChar);
        List<OptionPO> optionPOList = optionMapper.selectList(optionQueryWrapper);
        List<String> imageBelongIds = new ArrayList<>();

        if(ObjectUtils.isNotEmpty(optionPOList)){
            //从选项中提出选项id，用于图片查询
            List<String> ids = optionPOList.stream().map(OptionPO::getId).collect(Collectors.toList());
            imageBelongIds.addAll(ids);
        }
        imageBelongIds.addAll(tPQuestionIds);//试题id也加入图像查询
        //查询出相关的图像List
        LambdaQueryWrapper<ImagePO> imageQueryWrapper = new LambdaQueryWrapper<>();
        imageQueryWrapper.in(ImagePO::getBelongSecondlyId,imageBelongIds);
        List<ImagePO> imagePOList = imageMapper.selectList(imageQueryWrapper);
        Map<String, List<ImagePO>> imageMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(imagePOList)){
            //将图像按照归属对象分组存放
            imageMap = imagePOList.stream().collect(Collectors.groupingBy(ImagePO::getBelongSecondlyId));
        }

        //将optionPOList转为VOList,并封装进图片
        List<OptionVO> optionVOList = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(optionPOList)){
            for(OptionPO optionPO:optionPOList){
                OptionVO optionVO = new OptionVO();
                BeanUtils.copyProperties(optionPO,optionVO);
                optionVO.setPicList(imageMap.get(optionPO.getId()));
                optionVOList.add(optionVO);
            }
        }
        Map<String, List<OptionVO>> optionVOMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(optionVOList)){
            //optionVOList按照所属试卷试题questionId分组存放
            optionVOMap = optionVOList.stream().collect(Collectors.groupingBy(OptionVO::getBelongQuestionId));
        }


        //遍历试题 tPQuestionPOList 进行封装，将tPQuestionPO转为VO,并封装进图片和选项
        for(TestPaperQuestionPO tPQuestionPO:tPQuestionPOList){
            TestPaperQuestionVO tPQuestionVO = new TestPaperQuestionVO();
            BeanUtils.copyProperties(tPQuestionPO,tPQuestionVO);
            tPQuestionVO.setOptionList(optionVOMap.get(tPQuestionPO.getId()));
            tPQuestionVO.setPicList(imageMap.get(tPQuestionPO.getId()));
            tPQuestionVOS.add(tPQuestionVO);
        }

        redisTemplate.opsForValue().set(testPaperId,tPQuestionVOS,60, TimeUnit.SECONDS);

        return tPQuestionVOS;
    }

//    被改写
//    public List<TestPaperQuestionVO> getTestPaperQuestion(String testPaperId){
//        //查询试卷下的所有试卷-试题关联信息
//        LambdaQueryWrapper<TestPaperQuestionPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.eq(TestPaperQuestionPO::getTestPaperId,testPaperId)
//                .orderByAsc(TestPaperQuestionPO::getSort);
//        List<TestPaperQuestionPO> tPQuestionPOList = testPaperQuestionMapper.selectList(lambdaQueryWrapper);
//        //提取出questionId用于查询
//        List<String> questionIds = tPQuestionPOList.stream().map(TestPaperQuestionPO::getQuestionId).collect(Collectors.toList());
//        List<TestPaperQuestionVO> tPQuestionVOList = new ArrayList<>();
//        if(ObjectUtils.isEmpty(questionIds)){
//            return tPQuestionVOList;
//        }
//        //查出所有试题VO
//        List<QuestionVO> questionVOs = questionService.getQuestionByIds(questionIds);
//        //questionVOs转为map
//        Map<String,QuestionVO> questionVOMap  = questionVOs.stream().collect(Collectors.toMap(QuestionVO::getId, Function.identity()));
//
//        for(TestPaperQuestionPO tPQuestionPO:tPQuestionPOList){
//            TestPaperQuestionVO tPQuestionVO = new TestPaperQuestionVO();
//            BeanUtils.copyProperties(tPQuestionPO,tPQuestionVO);
//            QuestionVO questionVO = questionVOMap.get(tPQuestionPO.getQuestionId());
//            tPQuestionVO.setHasPic(questionVO.getHasPic());
//            tPQuestionVO.setPicList(questionVO.getPicList());
//            tPQuestionVO.setQuestionType(questionVO.getQuestionType());
//            tPQuestionVO.setOptionList(questionVO.getOptionList());
//            tPQuestionVO.setAnswer(questionVO.getAnswer());
//            tPQuestionVO.setContent(questionVO.getContent());
//            tPQuestionVO.setDifficulty(questionVO.getDifficulty());
//            tPQuestionVOList.add(tPQuestionVO);
//        }
//        return tPQuestionVOList;
//    }


    /**
     * 根据试卷试题 ids,删除试卷试题及关联的选项、图片
     * @param tPQuestionIds
     * @return
     */
    public int deleteTPQuestions(List<String> tPQuestionIds){
        //删除选项和图片
        optionService.deleteOptionAndImg(tPQuestionIds);
        //删除试题
        return testPaperQuestionMapper.deleteBatchIds(tPQuestionIds);
    }

    @Transactional
    public int save(TestPaperPO testPaperPO,List<TestPaperQuestionPO> testPaperQuestionPOS){
        //== 1,删除所有试卷试题试题，删除选项和图片。
        //查询所有旧试卷试题
        LambdaQueryWrapper<TestPaperQuestionPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TestPaperQuestionPO::getTestPaperId,testPaperPO.getId());
        List<TestPaperQuestionPO> tPQuestionPOList = testPaperQuestionMapper.selectList(lambdaQueryWrapper);
        if(ObjectUtils.isNotEmpty(tPQuestionPOList)){
            //提取试卷试题id
            List<String> tPQuestionIds = tPQuestionPOList.stream()
                    .map(TestPaperQuestionPO::getId).collect(Collectors.toList());
            //从数据库删除
            deleteTPQuestions(tPQuestionIds);
            //从redis中删除
            redisTemplate.delete(testPaperPO.getId());
        }
        if(ObjectUtils.isEmpty(testPaperQuestionPOS)){//试卷没有新试题
            return 0;
        }

        //=== 2,重新增加新试题（实例化试题、选项、图片
        //提取题库试题id
        List<String> questionIds = testPaperQuestionPOS.stream()
                .map(TestPaperQuestionPO::getQuestionId).collect(Collectors.toList());
        //从题库查询出所有试题
        List<QuestionPO> questionPOList = questionService.getQuestionPOs(questionIds);
        //questionPOList 根据questionId 转为map
        Map<String, QuestionPO> questionMap = questionPOList.stream().collect(Collectors.toMap(QuestionPO::getId, Function.identity()));
        //根据 questionIds 查询所有选项
        LambdaQueryWrapper<OptionPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(OptionPO::getBelongQuestionId,questionIds);
        List<OptionPO> allOptionPOList = optionMapper.selectList(queryWrapper);
        //allOptionPOList 根据questionId分组
        Map<String, List<OptionPO>> optionListMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(allOptionPOList)){
            optionListMap = allOptionPOList.stream().collect(Collectors.groupingBy(OptionPO::getBelongQuestionId));
        }
        //根据 questionIds 查询所有图片
        LambdaQueryWrapper<ImagePO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ImagePO::getBelongId,questionIds);
        List<ImagePO> allImagePOList = imageMapper.selectList(wrapper);
        //根据所属二级对象分组
        Map<String, List<ImagePO>> imagePOListMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(allImagePOList)){
            imagePOListMap = allImagePOList.stream().collect(Collectors.groupingBy(ImagePO::getBelongSecondlyId));
        }

        List<OptionPO> optionPOListAdd = new ArrayList<>();
        List<ImagePO> imagePOListAdd = new ArrayList<>();

        //实例化试题到试卷试题表
        for(TestPaperQuestionPO testPaperQuestionPO:testPaperQuestionPOS){
            QuestionPO questionPO = questionMap.get(testPaperQuestionPO.getQuestionId());
            //.....其他信息分组，排序，试题信息。。。
            BeanUtils.copyProperties(questionPO,testPaperQuestionPO);


            testPaperQuestionPO.setRightRate(BigDecimal.valueOf(0));//初始化正确率
            testPaperQuestionPO.setTestPaperId(testPaperPO.getId());
            String testPaperQuestionId = UUID.randomUUID().toString();//试卷试题id
            testPaperQuestionPO.setId(testPaperQuestionId);
//            testPaperQuestionPO.se

            //实例化试题对应的选项
            List<OptionPO> optionPOList = optionListMap.get(testPaperQuestionPO.getQuestionId());//题库试题id
            if(ObjectUtils.isNotEmpty(optionPOList)){
                for(OptionPO optionPO:optionPOList){
                    OptionPO optionPOAdd = new OptionPO();
                    BeanUtils.copyProperties(optionPO,optionPOAdd);
                    String tPQuestionOptionId = UUID.randomUUID().toString();
                    optionPOAdd.setId(tPQuestionOptionId);
                    optionPOAdd.setBelongQuestionId(testPaperQuestionId);
                    optionPOListAdd.add(optionPOAdd);
                    //实例化选项图片
                    List<ImagePO> optionImagePOList = imagePOListMap.get(optionPO.getId());
                    if(ObjectUtils.isNotEmpty(optionImagePOList)){
                        for(ImagePO imagePO:optionImagePOList){
                            ImagePO imagePOAdd = new ImagePO();
                            imagePOAdd.setId(UUID.randomUUID().toString());
                            imagePOAdd.setBelongId(testPaperQuestionId);
                            imagePOAdd.setBelongSecondlyId(tPQuestionOptionId);
                            imagePOAdd.setBelongType(imagePO.getBelongType());
                            imagePOAdd.setPath(imagePO.getPath());
                            imagePOListAdd.add(imagePOAdd);
                        }
                    }
                }
            }
            //实例化试题图片
            List<ImagePO> questionImagePOList = imagePOListMap.get(testPaperQuestionPO.getQuestionId());
            if(ObjectUtils.isNotEmpty(questionImagePOList)){
                for(ImagePO imagePO:questionImagePOList){
                    ImagePO imagePOAdd = new ImagePO();
                    imagePOAdd.setId(UUID.randomUUID().toString());
                    imagePOAdd.setBelongId(testPaperQuestionId);
                    imagePOAdd.setBelongSecondlyId(testPaperQuestionId);
                    imagePOAdd.setBelongType(imagePO.getBelongType());
                    imagePOAdd.setPath(imagePO.getPath());
                    imagePOListAdd.add(imagePOAdd);
                }
            }

        }

        //更新试卷信息
        testPaperMapper.updateById(testPaperPO);
        //保存选项
        if(ObjectUtils.isNotEmpty(optionPOListAdd)){
            optionMapper.insertBatchSomeColumn(optionPOListAdd);
        }
        //保存图片
        if(ObjectUtils.isNotEmpty(imagePOListAdd)){
            imageMapper.insertBatchSomeColumn(imagePOListAdd);
        }
        //保存试卷试题
        return testPaperQuestionMapper.insertBatchSomeColumn(testPaperQuestionPOS);
    }


}
